﻿using BCCommon;
using BCData.Common.News.ContentCategory;
using BCDto.Common.News.ContentCategory;
using BCEntity.Common.EntityNameConst;
using BCEntity.Common.News.ContentCategory;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BCService.Common.News.ContentCategory
{
    public class ContentCategoryService : IContentCategoryService
    {
        private readonly IRedisService redisService;
        private readonly IContentCategoryData contentCategoryData;
        private readonly string key = string.Format("{0}", EntityNameConst.ContentCategoryEntity);

        public ContentCategoryService(IRedisService redisService,IContentCategoryData contentCategoryData)
        {
            this.redisService = redisService;
            this.contentCategoryData = contentCategoryData;
        }

        public PageableList<ContentCategoryDto> Query(int? categoryLevel, string categoryName, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            var data = contentCategoryData.Query(categoryLevel, categoryName, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
            var list = contentCategoryData.GetList().GetAwaiter().GetResult();
            var result = new List<ContentCategoryDto>();
            foreach (ContentCategoryEntity entity in data.Item1)
            {
                ContentCategoryDto dto = entity.As<ContentCategoryDto>();
                dto.Key = dto.ContentCategoryId.ToString();
                if (!list.Any(p =>p.ParentCategoryId==0))
                {
                    result.Add(dto);
                }
                else
                {
                    var children = GetContentCategoryChildren(list, dto.ContentCategoryId);
                    dto.Children = children;
                    result.Add(dto);
                }
            }

            return new PageableList<ContentCategoryDto>
            {
                Count = data.Item2,
                Items = result.As<IEnumerable<ContentCategoryDto>>()
            };
        }
        private List<ContentCategoryDto> GetContentCategoryChildren(IEnumerable<ContentCategoryEntity> contentCategoryEntities, int contentCategoryId)
        {
            List<ContentCategoryDto> list = new List<ContentCategoryDto>();
            foreach (ContentCategoryEntity entity in contentCategoryEntities.Where(p => p.ParentCategoryId == contentCategoryId))
            {
                ContentCategoryDto dto = entity.As<ContentCategoryDto>();
                dto.Key = string.Format("{0}-{1}", contentCategoryId, dto.ContentCategoryId.ToString());

                if (contentCategoryEntities.Any(p => p.ParentCategoryId == dto.ContentCategoryId))
                {
                    var children = GetContentCategoryChildren(contentCategoryEntities, dto.ContentCategoryId);
                    dto.Children = children;
                    list.Add(dto);
                }
                else
                {
                    dto.IsLeaf = true;
                    list.Add(dto);
                }
            }
            return list;
        }

        public ContentCategoryDto Create(ContentCategoryRequestDto dto)
        {
            if (this.contentCategoryData.CheckContentCategoryExists(dto.CategoryName).Result)
            {
                throw new ArgumentException(string.Format("分类【{0}】已存在。", dto.CategoryName));
            }
            var entity = dto.As<ContentCategoryEntity>();
            if (entity.CategoryLevel > 3)
            {
                throw new ArgumentException(string.Format("分类级别不能大于三级。"));
            }
            return this.contentCategoryData.Add(entity).Result.As<ContentCategoryDto>();
        }

        public ContentCategoryDto Update(int contentCategoryId, ContentCategoryRequestDto dto)
        {
            ContentCategoryEntity contentCategoryEntity = this.contentCategoryData.GetEntity(contentCategoryId).Result;
            if (contentCategoryEntity == null)
            {
                throw new ArgumentException("此分类不存在。");
            }
            if (contentCategoryEntity.IsSystem)
            {
                throw new ArgumentException("系统分类不允许修改。");
            }
            if (!contentCategoryEntity.CategoryName.Equals(dto.CategoryName))
            {
                if (this.contentCategoryData.CheckContentCategoryExists(dto.CategoryName).Result)
                {
                    throw new ArgumentException("新分类名称已存在。");
                }
            }
            var entity = dto.As<ContentCategoryEntity>();
            if (entity.CategoryLevel > 3)
            {
                throw new ArgumentException(string.Format("分类级别不能大于三级。"));
            }
            entity.ContentCategoryId = contentCategoryId;
            return this.contentCategoryData.Update(entity).Result.As<ContentCategoryDto>();
        }

        public bool Delete(int contentCategoryId)
        {
            ContentCategoryEntity contentCategoryEntity = this.contentCategoryData.GetEntity(contentCategoryId).Result;
            if (contentCategoryEntity == null)
            {
                throw new ArgumentException("此分类不存在。");
            }
            if (contentCategoryEntity.IsSystem)
            {
                throw new ArgumentException("系统分类不允许删除。");
            }
            if (contentCategoryData.CheckContentCategoryChildrenExists(contentCategoryId).Result)
            {
                throw new ArgumentException("此分类存在下级分类，不允许删除。请先删除下级分类。");
            }
            return this.contentCategoryData.Delete(contentCategoryId).Result;
        }

        public ContentCategoryDto GetContentCategoryById(int contentCategoryId)
        {
            return this.contentCategoryData.GetEntity(contentCategoryId).Result.As<ContentCategoryDto>();
        }

        public IEnumerable<ContentCategoryDto> GetNextCategoryById(int contentCategoryId)
        {
            return this.contentCategoryData.GetNextCategoryById(contentCategoryId).Result.As<IEnumerable<ContentCategoryDto>>();
        }

        public IEnumerable<ContentCategoryDto> GetLevelCategoryList(int level)
        {
            return this.contentCategoryData.GetLevelCategoryList(level).Result.As<IEnumerable<ContentCategoryDto>>();
        }

        #region 检查内容分类是否存在
        public bool Exists(int contentCategoryId)
        {
            return this.contentCategoryData.CheckContentCategoryExists(contentCategoryId).GetAwaiter().GetResult();
        }
        #endregion

        #region 启用内容分类
        public bool Enabled(int contentCategoryId)
        {
            if (!this.Exists(contentCategoryId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var result = this.contentCategoryData.Enabled(contentCategoryId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, contentCategoryId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 禁用内容分类
        public bool Disabled(int contentCategoryId)
        {
            if (!this.Exists(contentCategoryId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var result = this.contentCategoryData.Disabled(contentCategoryId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, contentCategoryId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion
    }
}
